package model;

import message.GameOverMessage;
import message.MovePiecesMessage;
import socket.ChessClient;
import thread.AudioPlayerThread;
import thread.HumanThread;
import thread.RobotThread;
import view.OnlineRoom;
import view.Room;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;

/**
 * 五子棋棋盘.
 *
 * @author 任禹名
 */
public class ChessBoard extends JPanel {

    private int[][] drawMark = new int[15][15];//标记最后一个下的棋子，方便框出
    private ChessAction chessAction = new ChessAction();
    private int[][] nowTable = chessAction.getNowTable();
    private boolean robotExit = false;
    private boolean lock = false;
    private int row; // 鼠标点击的坐标
    private int line; // 鼠标点击的坐标
    private Room room;
    private OnlineRoom onlineRoom;
    private ChessBoard chessBoard = this;
    private int mode;
    private int limit;
    private final int BLACK = 1, WHITE = 2;
    private int colorNow, colorHuman = 0, colorRobot = 0, chessCnt = 0;
    private boolean online;

    private RobotThread robotThread = new RobotThread(chessAction, this); // 机器人线程
    private HumanThread humanThread = new HumanThread(chessAction, this); // 人类线程
    private AudioPlayerThread audioPlayerThread = new AudioPlayerThread("resource/audio/down.wav");
    private AudioPlayerThread audioStopPlayer = new AudioPlayerThread("resource/audio/stop.wav");


    public int getMode() {
        return mode;
    }

    public ChessAction getChessAction() {
        return chessAction;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public void setChessCnt(int chessCnt) {
        this.chessCnt = chessCnt;
    }

    public int getColorHuman() {
        return colorHuman;
    }

    public void setLock(boolean lock) {
        this.lock = lock;
    }

    public int getChessCnt() {
        return chessCnt;
    }

    /**
     * 人人模式的构造函数.
     *
     * @param room
     * @param online
     */
    public ChessBoard(JFrame room, boolean online) {
        if (online) {
            this.onlineRoom = (OnlineRoom) room;
        } else {
            this.room = (Room) room;
            this.limit = this.room.getLimit();
        }
        this.mode = 0;
        this.online = online;
        chessAction.setChessBoard(this);

        chessCnt = 0;
        chessAction.reset();

        this.setBounds(0, 0, 515, 515);
        humanThread.start();
    }

    /**
     * 人机模式的构造函数.
     *
     * @param room
     * @param mode
     */
    public ChessBoard(Room room, int mode) {
        this.room = room;
        this.mode = mode;
        chessAction.setChessBoard(this);
        limit = room.getLimit();
        chessCnt = 0;
        chessAction.reset();
        colorHuman = room.getChooseColor();
        colorRobot = colorHuman == BLACK ? WHITE : BLACK;
        robotThread.setDegree(mode);

        this.setBounds(0, 0, 515, 515);
        humanThread.start();
        robotThread.start();
    }

    /**
     * 重写画笔函数，进行棋子的绘制.
     *
     * @param g
     */
    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(new ImageIcon("resource/img/pan.png").getImage(), -8, -8, 565, 565, this);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.black);
        char ch = 'A';
        g.setFont(new Font("宋体", Font.BOLD, 12));

        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                if (nowTable[i][j] != 0) {
                    int m, n;
                    m = i * 34 + 35;
                    n = j * 34 + 35;
                    Ellipse2D ellipse = new Ellipse2D.Double();
                    Ellipse2D ellipse2D = new Ellipse2D.Double();
                    ellipse.setFrameFromCenter(m, n, m + 14, n + 14);
                    ellipse2D.setFrameFromCenter(m + 1, n - 1, m + 15, n + 13);
                    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
                    g2.setComposite(AlphaComposite.getInstance(
                            AlphaComposite.SRC_OVER, 0.5f));

                    // 白子
                    GradientPaint gp1 = new GradientPaint(
                            (float) ellipse.getMinX(),
                            (float) ellipse.getMinY(),
                            new Color(174, 173, 171),
                            (float) ellipse.getMaxX(),
                            (float) ellipse.getMaxY(), new Color(116, 115, 114));
                    GradientPaint gp3 = new GradientPaint(
                            (float) ellipse.getMinX(),
                            (float) ellipse.getMinY(), Color.white,
                            (float) ellipse.getMaxX(),
                            (float) ellipse.getMaxY(), Color.gray);
                    // 黑子
                    GradientPaint gp2 = new GradientPaint(
                            (float) ellipse.getMinX() - 1,
                            (float) ellipse.getMinY() - 1, Color.white,
                            (float) ellipse.getCenterX() - 1,
                            (float) ellipse.getCenterY() - 1, Color.gray);
                    GradientPaint gp4 = new GradientPaint(
                            (float) ellipse.getMinX() - 1,
                            (float) ellipse.getMinY() - 1, Color.white,
                            (float) ellipse.getCenterX() - 1,
                            (float) ellipse.getCenterY() - 1, Color.black);
                    // 黑子
                    // System.out.println("m=" + m + "n=" + n);
                    if (nowTable[i][j] == BLACK) {
                        // System.out.println("棋桌在"+m+","+n+"处画了一个黑子");
                        g2.setPaint(gp2);
                        g2.fill(ellipse);
                        g2.setPaint(gp4);

                    } else if (nowTable[i][j] == WHITE) {// 白子
                        // System.out.println("棋桌在"+m+","+n+"处画了一个白子");
                        g2.setPaint(gp1);
                        g2.fill(ellipse);
                        g2.setPaint(gp3);

                    } else {
                        System.out.println("定位不准确，未获得棋子颜色");
                    }
                    g2.setComposite(AlphaComposite.getInstance(
                            AlphaComposite.SRC_OVER, 1));
                    g2.fill(ellipse2D);
                    if (drawMark[i][j] == 1) {//画出最后一个棋子的位置，用红色十字
                        g2.setColor(Color.red);
                        g2.drawLine(m - 3, n, m + 3, n);
                        g2.drawLine(m, n - 3, m, n + 3);
                        drawMark[i][j] = 0;
                    }
                }
            }
        }
    }

    /**
     * 悔棋
     */
    public void back() {
        int flag = chessAction.deleteChess(limit, 1);
        if (flag == -1)
            room.noRegretTimes();
        else if (flag == 0)
            room.noChess();
        else if (colorHuman == WHITE && chessCnt == 1)
            room.noChess();
        else {
            if (colorHuman != 0 && colorNow != colorHuman) {
                chessAction.deleteChess(limit, 1);
                chessCnt--;
            }
            limit--;
            chessCnt--;
        }
        repaint();
        System.out.println(chessCnt);
    }

    /**
     * 对于在线模式的发送悔棋请求玩家的悔棋操作.
     */
    public void backForOnline() {

        int colorNow = chessCnt % 2 + 1;
        if ((onlineRoom.isLeft() && colorNow != BLACK) || (!onlineRoom.isLeft() && colorNow != WHITE)) {
            chessAction.deleteChess(10, 1);
            chessCnt--;
        } else {
            chessAction.deleteChess(10, 2);
            chessCnt -= 2;
        }
        repaint();
        System.out.println(chessCnt);
    }

    /**
     * 对于在线模式的收到悔棋请求玩家的悔棋操作.
     */
    public void backForAnotherOnline() {

        int colorNow = chessCnt % 2 + 1;
        if ((onlineRoom.isLeft() && colorNow != BLACK) || (!onlineRoom.isLeft() && colorNow != WHITE)) {
            chessAction.deleteChess(10, 2);
            chessCnt -= 2;
        } else {
            chessAction.deleteChess(10, 1);
            chessCnt--;
        }
        repaint();
        System.out.println(chessCnt);
    }

    /**
     * 在线模式收到落子报文的操作.
     *
     * @param chess
     * @param backChess
     * @param x
     * @param y
     */
    public void downChessForOnline(int[][] chess, boolean backChess, int x, int y) {
        int chessColor = chessCnt % 2 + 1;
        chessCnt++;
        System.out.println("我是TRUE：" + onlineRoom.isCanPlay());
        chessAction.downChess(x, y, chessColor);
        System.out.println(x + "," + y);
        drawMark[x][y] = 1;
        repaint();
        audioPlayerThread.run();
    }

    /**
     * 内部类,鼠标点击处理.
     *
     * @author 任禹名
     */
    public class MouseHandler extends MouseAdapter {
        /**
         * 处理鼠标左键单击.
         *
         * @param event
         * @author 任禹名
         */
        public void mousePressed(MouseEvent event) {
            synchronized (chessBoard) {
                int x = event.getX();
                int y = event.getY();
                System.out.println(x);
                System.out.println(y);

                if (x > 30 && x < 535 && y > 30 && y < 535) {
                    int colorTmp = 0;
                    row = (x - 21) / 34;
                    line = (y - 21) / 34;
                    colorNow = chessCnt % 2 + 1;
                    if (!online) {
                        if (colorHuman != 0) {
                            colorTmp = colorHuman;
                        } else {
                            colorTmp = colorNow;
                        }
                        if (chessAction.downChess(row, line, colorTmp)) {
                            chessCnt++;
                            System.out.println(chessCnt);
                            drawMark[row][line] = 1;
                            lock = true;
                            repaint();
                            audioPlayerThread.run();
                            if (chessCnt == 225) {
                                room.gameDraw();
                            } else if (chessAction.isWin(row, line)) {
                                if (mode == 0) {
                                    room.win(colorNow);
                                } else {
                                    room.win();
                                }
                                chessBoard.notifyAll();
                            } else {
                                chessBoard.notifyAll();
                            }
                        } else {
                            audioStopPlayer.run();
                            JOptionPane.showMessageDialog(room, "该位置已有棋子");
                        }
                    } else {
                        if (onlineRoom.isLeft()) {
                            colorTmp = BLACK;
                        } else {
                            colorTmp = WHITE;
                        }
                        if (onlineRoom.isCanPlay()) {
                            if (chessAction.downChess(row, line, colorTmp)) {
                                chessCnt++;
                                System.out.println(chessCnt);
                                onlineRoom.setCanPlay(false);
                                MovePiecesMessage movePiecesMessage = new MovePiecesMessage(onlineRoom.getRid(), onlineRoom.isLeft, nowTable, false, row, line);
                                ChessClient.getInstance().sendMessage(movePiecesMessage);
                                drawMark[row][line] = 1;
                                repaint();
                                audioPlayerThread.run();
                                if (chessCnt == 225) {
                                    onlineRoom.gameDraw();
                                } else {
                                    //由获胜的一方发送报文
                                    if (onlineRoom.isLeft) {
                                        if (colorNow == BLACK && chessAction.isWin(row, line)) {//黑棋赢了，发送游戏结束报文
                                            GameOverMessage gameOverMessage = new GameOverMessage(onlineRoom.getRid(), onlineRoom.isLeft);
                                            ChessClient.getInstance().sendMessage(gameOverMessage);
                                        }
                                    } else {
                                        if (colorNow == WHITE && chessAction.isWin(row, line)) {//白棋赢了
                                            GameOverMessage gameOverMessage = new GameOverMessage(onlineRoom.getRid(), onlineRoom.isLeft);
                                            ChessClient.getInstance().sendMessage(gameOverMessage);
                                        }
                                    }
                                }
                            } else {
                                audioStopPlayer.run();
                                JOptionPane.showMessageDialog(onlineRoom, "该位置已有棋子");
                            }
                        }
                    }

                } else {
                    JOptionPane.showMessageDialog(room, "请将棋子放进棋盘内");
                }


            }
        }
    }

    /**
     * 机器人线程.
     *
     * @param degree
     * @author 任禹名
     */
    public synchronized void robotChess(int degree) {
        // TODO Auto-generated method stub
        System.out.println("机器线程开启");
        synchronized (chessBoard) {
            while (true) {
                if (colorHuman == BLACK) {
                    if (!lock) {
                        try {
                            chessBoard.wait();
                        } catch (InterruptedException e) {
                            continue;
                        }
                    } else {
                        try {
                            Thread.sleep(300);
                        } catch (InterruptedException e) {
                            continue;
                        }
                        int[] XY = chessAction.downChessByAI(row, line, degree, colorRobot);
                        drawMark[XY[0]][XY[1]] = 1;
                        colorNow = chessCnt % 2 + 1;
                        chessAction.downChess(XY[0], XY[1], colorRobot);
                        repaint();
                        chessCnt++;
                        lock = false;
                        audioPlayerThread.run();
                        if (chessCnt == 225) {
                            room.gameDraw();
                        } else if (chessAction.isWin(XY[0], XY[1])) {
                            room.defeat();
                        } else {
                            chessBoard.notifyAll();
                        }
                    }
                } else {
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        continue;
                    }
                    int[] XY = chessAction.downChessByAI(row, line, degree, colorRobot);
                    drawMark[XY[0]][XY[1]] = 1;
                    colorNow = chessCnt % 2 + 1;
                    chessAction.downChess(XY[0], XY[1], colorRobot);
                    repaint();
                    chessCnt++;
                    lock = false;
                    audioPlayerThread.run();
                    if (chessCnt == 225) {
                        room.gameDraw();
                    } else if (chessAction.isWin(XY[0], XY[1])) {
                        room.defeat();
                        lock = true;
                    } else {
                        chessBoard.notifyAll();
                    }

                    if (!lock) {
                        try {
                            chessBoard.wait();
                        } catch (InterruptedException e) {
                            continue;
                        }
                    }
                }
            }
        }
    }

    /**
     * 重置机器人.
     *
     * @author 任禹名
     */
    public void robotReset() {
        robotThread.interrupt();
    }


}
